﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Utilities;
using System.Reflection;
using System.IO;

namespace SPVisualDev.Services
{
    public interface IExplorerObjectContainer
    {
        List<string> GetSubGroups();
        List<IExplorerObjectContainer> GetChildren(string SubGroup);
        bool CanHaveChildren { get; set; }
        Dictionary<string, Uri> BrowseToURLs { get; set; }
        string Title { get; set; }
        object GetProperties(bool UseSPObjectModel);

    }

    public interface IExplorerUrlContainer
    {
        string Url { get; set; }
    }

    [DataContract]
    public class ExFarm : IExplorerObjectContainer
    {
        public ExFarm()
        {
        }

        public ExFarm(string Name)
        {
            this.Title = Name;
        }

        [DataMember]
        public string Title
        {
            get;
            set;
        }

        [DataMember]
        public bool CanHaveChildren
        {
            get { return true; }
            set { }
        }

        [DataMember]
        public Dictionary<string, Uri> BrowseToURLs
        {
            get { return null; }
            set { }
        }

        public List<string> GetSubGroups()
        {
            List<string> ret = new List<string>();

            ret.Add("Farm features");
            ret.Add("Solutions");
            ret.Add("Web applications");

            return ret;
        }

        public List<IExplorerObjectContainer> GetChildren(string SubGroup)
        {
            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();

            if (SubGroup == "Farm features")
            {
                SPWebService websvc = SPFarm.Local.Servers.GetValue<SPWebService>(string.Empty);

                ret = ExFeaturesCollection.CreateCollection("Farm", null);
            }
            else if (SubGroup == "Solutions")
            {
                ret = ExFarmSolution.CreateCollection(SPFarm.Local.Solutions);
            }
            else if (SubGroup == "Web applications")
            {
                ret = ExWebApplication.CreateCollection(SPWebService.ContentService.WebApplications);

                ret.AddRange(ExWebApplication.CreateCollection(SPWebService.AdministrationService.WebApplications));
            }

            return ret;
        }

        public object GetProperties(bool UseSPObjectModel)
        {
            if (UseSPObjectModel)
            {
                return SPFarm.Local;
            }
            else
            {
                return Common.GetPropertiesFromObject(SPFarm.Local);
            }
        }


    }

    [DataContract]
    public class ExWebApplication : IExplorerObjectContainer, IExplorerUrlContainer
    {
        [DataMember]
        public string Title { get; set; }

        [DataMember]
        public string Url { get; set; }

        [DataMember]
        public bool CanHaveChildren
        {
            get { return true; }
            set { }
        }

        [DataMember]
        public Dictionary<string, Uri> BrowseToURLs { get; set; }

        public List<string> GetSubGroups()
        {
            List<string> ret = new List<string>();

            ret.Add("Web application features");
            ret.Add("Sites");

            return ret;
        }

        public List<IExplorerObjectContainer> GetChildren(string SubGroup)
        {
            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();

            SPWebApplication webapp = SPWebApplication.Lookup(new Uri(this.Url));

            if (SubGroup == "Web application features")
            {
                ret = ExFeaturesCollection.CreateCollection("WebApplication", this.Url);
            }
            else if (SubGroup == "Sites")
            {
                ret = ExSite.CreateCollection(webapp.Sites);
            }
            
            return ret;
        }

        public object GetProperties(bool UseSPObjectModel)
        {
            SPWebApplication webapp = SPWebApplication.Lookup(new Uri(this.Url));
            if (UseSPObjectModel)
            {
                return webapp;
            }
            else
            {
                return Common.GetPropertiesFromObject(webapp);
            }
        }

        public static List<IExplorerObjectContainer> CreateCollection(SPWebApplicationCollection collection)
        {
            string admin_url = SPAdministrationWebApplication.Local.GetResponseUri(SPUrlZone.Default).ToString();
            if (admin_url.EndsWith("/"))
                admin_url = admin_url.Substring(0, admin_url.Length - 1);

            admin_url += "/_admin/applications.aspx?WebApplicationId=";

            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();
            foreach (SPWebApplication webapp in collection)
            {
                ExWebApplication container = new ExWebApplication();
                container.Title = string.IsNullOrEmpty(webapp.Name) ? webapp.DefaultServerComment : webapp.Name;
                container.Url = webapp.AlternateUrls.GetResponseUrl(SPUrlZone.Default).IncomingUrl;


                container.BrowseToURLs = new Dictionary<string, Uri>();
                container.BrowseToURLs.Add("More info", new Uri(admin_url + SPEncode.UrlEncode(webapp.Id.ToString("D"))));
                container.BrowseToURLs.Add("Root site", new Uri(container.Url));

                ret.Add(container);
            }

            return ret;
        }
    }

    [DataContract]
    public class ExSite : IExplorerObjectContainer, IExplorerUrlContainer
    {
        [DataMember]
        public string Title { get; set; }

        [DataMember]
        public string Url { get; set; }

        [DataMember]
        public bool CanHaveChildren
        {
            get { return true; }
            set { }
        }

        [DataMember]
        public Dictionary<string, Uri> BrowseToURLs { get; set; }

        [DataMember]
        public string MoreInfoURL { get; set;}

        public List<string> GetSubGroups()
        {
            List<string> ret = new List<string>();

            ret.Add("Site features");
            ret.Add("Webs");
            ret.Add("Lists");
            ret.Add("Fields");
            ret.Add("Content types");
            //ret.Add("Users");

            return ret;
        }

        public List<IExplorerObjectContainer> GetChildren(string SubGroup)
        {
            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();

            using (SPSite site = new SPSite(this.Url))
            {
                if (SubGroup == "Site features")
                {
                    ret = ExFeaturesCollection.CreateCollection("Site", this.Url);
                }
                else
                {
                    using (SPWeb web = site.RootWeb)
                    {
                        if (SubGroup == "Webs")
                        {
                            ExWeb container = new ExWeb();
                            container.Title = web.Title + " (root web)";
                            container.Url = web.Url;

                            container.BrowseToURLs = new Dictionary<string, Uri>();
                            container.BrowseToURLs.Add("Home page", new Uri(container.Url));
                            container.BrowseToURLs.Add("Settings", new Uri(container.Url + "/_layouts/settings.aspx"));
                            container.BrowseToURLs.Add("Users", new Uri(container.Url + "/_layouts/User.aspx"));

                            ret.Add(container);

                            ret.AddRange(ExWeb.CreateCollection(web.Webs));
                        }
                        else if (SubGroup == "Lists")
                        {
                            ret = ExList.CreateCollection(web.Lists);
                        }
                        else if (SubGroup == "Content types")
                        {
                            ret = ExContentType.CreateCollection(web.ContentTypes, web);
                        }
                        else if (SubGroup == "Fields")
                        {
                            ret = ExField.CreateCollection(web.Fields);
                        }
                    }
                }
            }

            return ret;
        }

        public object GetProperties(bool UseSPObjectModel)
        {
            using (SPSite site = new SPSite(this.Url))
            {
                if (UseSPObjectModel)
                {
                    return site;
                }
                else
                {
                    return Common.GetPropertiesFromObject(site);
                }
            }
        }

        public static List<IExplorerObjectContainer> CreateCollection(SPSiteCollection collection)
        {
            string admin_url = SPAdministrationWebApplication.Local.GetResponseUri(SPUrlZone.Default).ToString();
            if (admin_url.EndsWith("/"))
                admin_url = admin_url.Substring(0, admin_url.Length - 1);

            admin_url += "/_admin/SiteCollections.aspx?WebApplicationId=";

            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();

            foreach (SPSite site in collection)
            {
                try
                {
                    ExSite container = new ExSite();
                    container.Title = site.RootWeb.Title;
                    container.Url = site.Url;

                    container.BrowseToURLs = new Dictionary<string, Uri>();
                    container.BrowseToURLs.Add("Home page", new Uri(container.Url));
                    container.BrowseToURLs.Add("Settings", new Uri(container.Url + "/_layouts/settings.aspx"));
                    container.BrowseToURLs.Add("Users", new Uri(container.Url + "/_layouts/User.aspx"));
                    container.BrowseToURLs.Add("Administration", new Uri(admin_url +  site.WebApplication.Id.ToString("D")));

                    ret.Add(container);
                }
                finally
                {
                    site.Dispose();
                }
            }

            return ret;
        }
    }

    [DataContract]
    public class ExWeb : IExplorerObjectContainer, IExplorerUrlContainer
    {
        [DataMember]
        public string Title { get; set; }

        [DataMember]
        public string Url { get; set; }

        [DataMember]
        public bool CanHaveChildren
        {
            get { return true; }
            set { }
        }

        [DataMember]
        public Dictionary<string, Uri> BrowseToURLs { get; set; }

        public List<string> GetSubGroups()
        {
            List<string> ret = new List<string>();

            ret.Add("Web features");
            ret.Add("Webs");
            ret.Add("Lists");
            ret.Add("Content types");
            //ret.Add("Users");

            return ret;
        }

        public List<IExplorerObjectContainer> GetChildren(string SubGroup)
        {
            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();

            using (SPSite site = new SPSite(this.Url))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    if (SubGroup == "Web features")
                    {
                        ret = ExFeaturesCollection.CreateCollection("Web", this.Url);
                    }
                    else if (SubGroup == "Webs")
                    {
                        ret = ExWeb.CreateCollection(web.Webs);
                    }
                    else if (SubGroup == "Lists")
                    {
                        ret = ExList.CreateCollection(web.Lists);
                    }
                    else if (SubGroup == "Content types")
                    {
                        ret = ExContentType.CreateCollection(web.ContentTypes, web);
                    }
                    else if (SubGroup == "Fields")
                    {
                        ret = ExField.CreateCollection(web.Fields);
                    }
                }
            }

            return ret;
        }

        public object GetProperties(bool UseSPObjectModel)
        {
            using (SPSite site = new SPSite(this.Url))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    if (UseSPObjectModel)
                    {
                        return web;
                    }
                    else
                    {
                        return Common.GetPropertiesFromObject(web);
                    }
                }
            }
        }

        public static List<IExplorerObjectContainer> CreateCollection(SPWebCollection collection)
        {
            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();

            foreach (SPWeb web in collection)
            {
                try
                {
                    ExWeb container = new ExWeb();
                    container.Title = web.Title;
                    container.Url = web.Url;

                    container.BrowseToURLs = new Dictionary<string, Uri>();
                    container.BrowseToURLs.Add("Home page", new Uri(container.Url));
                    container.BrowseToURLs.Add("Settings", new Uri(container.Url + "/_layouts/settings.aspx"));
                    container.BrowseToURLs.Add("Users", new Uri(container.Url + "/_layouts/User.aspx"));

                    ret.Add(container);
                }
                finally
                {
                    web.Dispose();
                }
            }

            return ret;
        }

    }

    [DataContract]
    public class ExList : IExplorerObjectContainer, IExplorerUrlContainer
    {
        [DataMember]
        public string Title { get; set; }

        [DataMember]
        public string Url { get; set; }

        [DataMember]
        public bool CanHaveChildren 
        {
            get { return true; }
            set { }
        }

        [DataMember]
        public Dictionary<string, Uri> BrowseToURLs { get; set; }

        public List<string> GetSubGroups()
        {
            List<string> ret = new List<string>();

            ret.Add("Items");
            ret.Add("Event receivers");
            ret.Add("Content types");
            ret.Add("Fields");
            //ret.Add("Users");

            return ret;
        }

        public List<IExplorerObjectContainer> GetChildren(string SubGroup)
        {
            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();

            using (SPSite site = new SPSite(this.Url))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPList list = web.GetList(this.Url);

                    if (SubGroup == "Items")
                    {
                        throw new NotImplementedException();
                    }
                    else if (SubGroup == "Content types")
                    {
                        ret = ExContentType.CreateCollection(list.ContentTypes, list);
                    }
                    else if (SubGroup == "Fields")
                    {
                        ret = ExField.CreateCollection(list.Fields);
                    }
                    else if (SubGroup == "Event receivers")
                    {
                        ret = ExEventReceiver.CreateCollection(list.EventReceivers);
                    }
                }
            }

            return ret;
        }

        public object GetProperties(bool UseSPObjectModel)
        {
            using (SPSite site = new SPSite(this.Url))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPList list = web.GetList(this.Url);

                    if (UseSPObjectModel)
                    {
                        return list;
                    }
                    else
                    {
                        return Common.GetPropertiesFromObject(list);
                    }
                }
            }
        }

        public static List<IExplorerObjectContainer> CreateCollection(SPListCollection collection)
        {
            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();

            foreach (SPList list in collection)
            {
                ExList container = new ExList();
                container.Title = list.Title;
                container.Url = collection.Web.Site.MakeFullUrl(list.RootFolder.ServerRelativeUrl);

                container.BrowseToURLs = new Dictionary<string, Uri>();
                container.BrowseToURLs.Add("Browse to", new Uri(container.Url));
                container.BrowseToURLs.Add("Settings", new Uri(container.Url + "/_layouts/listedit.aspx?List=" + SPEncode.UrlEncode(list.ID.ToString())));

                ret.Add(container);
            }

            return ret;
        }
    }

    [DataContract]
    public class ExContentType : IExplorerObjectContainer
    {
        [DataMember]
        public string ParentObjectType
        {
            get;
            set;
        }

        [DataMember]
        public string ParentUrl
        {
            get;
            set;
        }

        [DataMember]
        public bool CanHaveChildren
        {
            get { return true; }
            set { }
        }

        [DataMember]
        public string Title
        {
            get;
            set;
        }

        [DataMember]
        public string ID
        {
            get;
            set;
        }

        [DataMember]
        public Dictionary<string, Uri> BrowseToURLs { get; set; }

        public List<string> GetSubGroups()
        {
            List<string> ret = new List<string>();
            ret.Add("Fields");
            ret.Add("Event receivers");

            return ret;
        }

        public List<IExplorerObjectContainer> GetChildren(string SubGroup)
        {
            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();

            using (SPSite site = new SPSite(this.ParentUrl))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPContentType ct;
                    if (this.ParentObjectType == typeof(ExWeb).Name)
                    {
                        ct = web.ContentTypes[this.Title];
                    }
                    else if (this.ParentObjectType == typeof(ExList).Name)
                    {
                        SPList list = web.GetList(this.ParentUrl);
                        ct = list.ContentTypes[this.Title];
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }

                    if (SubGroup == "Fields")
                    {
                        foreach (SPFieldLink link in ct.FieldLinks)
                        {
                            ExField field = new ExField();

                            field.Title = link.DisplayName;
                            field.ParentUrl = this.ParentUrl;

                            ret.Add(field);
                        }
                    }
                    else if (SubGroup == "Event receivers")
                    {
                        ret = ExEventReceiver.CreateCollection(ct.EventReceivers);
                    }
                }
            }

            return ret;

        }

        public object GetProperties(bool UseSPObjectModel)
        {
            using (SPSite site = new SPSite(this.ParentUrl))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPContentType ct;
                    if (string.Compare(web.Url, this.ParentUrl, true) == 0)
                    {
                        ct = web.ContentTypes[this.Title];
                    }
                    else
                    {
                        SPList list = web.GetList(this.ParentUrl);
                        ct = list.ContentTypes[this.Title];
                    }

                    if (UseSPObjectModel)
                    {
                        return ct;
                    }
                    else
                    {
                        return Common.GetPropertiesFromObject(ct);
                    }
                }
            }
        }

        public static List<IExplorerObjectContainer> CreateCollection(SPContentTypeCollection collection, object Parent)
        {
            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();

            foreach (SPContentType ct in collection)
            {
                ExContentType container = new ExContentType();
                container.Title = ct.Name;
                container.ID = ct.Id.ToString();

                container.BrowseToURLs = new Dictionary<string, Uri>();

                if (Parent is SPList)
                {
                    SPList list = Parent as SPList;
                    container.ParentUrl = list.ParentWeb.Site.MakeFullUrl(list.RootFolder.ServerRelativeUrl);
                    container.BrowseToURLs.Add("Browse to", new Uri(list.ParentWeb.Url + "/_ManageContentType.aspx?List=" + SPEncode.UrlEncode(list.ID.ToString()) + "&ctype=" + SPEncode.UrlEncode(ct.Id.ToString())));
                }
                else if (Parent is SPWeb)
                {
                    SPWeb web = Parent as SPWeb;
                    container.ParentUrl = web.Url;
                    container.BrowseToURLs.Add("Browse to", new Uri(web.Url + "/_ManageContentType.aspx?ctype=" + SPEncode.UrlEncode(ct.Id.ToString())));
                }

                ret.Add(container);
            }

            return ret;
        }

    }

    [DataContract]
    public class ExField : IExplorerObjectContainer
    {
        [DataMember]
        public string ParentUrl
        {
            get;
            set;
        }

        [DataMember]
        public bool CanHaveChildren
        {
            get { return false; }
            set { }
        }

        [DataMember]
        public string Title
        {
            get;
            set;
        }

        public List<string> GetSubGroups()
        {
            return null;
        }

        public List<IExplorerObjectContainer> GetChildren(string SubGroup)
        {
            return null;
        }

        [DataMember]
        public Dictionary<string, Uri> BrowseToURLs { get; set; }

        public object GetProperties(bool UseSPObjectModel)
        {
            using (SPSite site = new SPSite(this.ParentUrl))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPField field = web.Fields[this.Title];

                    if (UseSPObjectModel)
                    {
                        return field;
                    }
                    else
                    {
                        return Common.GetPropertiesFromObject(field);
                    }
                }
            }
        }

        public static List<IExplorerObjectContainer> CreateCollection(SPFieldCollection collection)
        {
            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();

            foreach (SPField fld in collection)
            {
                ExField container = new ExField();
                container.Title = fld.Title;
                container.ParentUrl = (collection.List != null) ? collection.List.ParentWeb.Url : collection.Web.Url;

                container.BrowseToURLs = new Dictionary<string, Uri>();
                if (collection.List != null)
                {
                    container.BrowseToURLs.Add("Browse to", new Uri(collection.Web.Url + "/_layouts/fldedit.aspx?List=" + SPEncode.UrlEncode(collection.List.ID.ToString()) + "&field=" + SPEncode.UrlEncode(fld.InternalName)));
                }
                else
                {
                    container.BrowseToURLs.Add("Browse to", new Uri(collection.Web.Url + "/_layouts/fldedit.aspx?field=" + SPEncode.UrlEncode(fld.InternalName)));
                }

                ret.Add(container);
            }

            return ret;
        }
    }

    [DataContract]
    public class ExFeaturesCollection : IExplorerObjectContainer
    {
        [DataMember]
        public string Title
        {
            get;
            set;
        }

        [DataMember]
        public string ParentUrl
        {
            get;
            set;
        }

        [DataMember]
        public string Scope
        {
            get;
            set;
        }

        [DataMember]
        public bool CanHaveChildren
        {
            get { return true; }
            set { }
        }

        [DataMember]
        public Dictionary<string, Uri> BrowseToURLs { get; set; }

        public List<string> GetSubGroups()
        {
            return null;
        }

        public List<IExplorerObjectContainer> GetChildren(string SubGroup)
        {
            /*
            if (this.Title == "Installed")
            {
                return ExFeature.CreateFarmInstalledCollection();
            }
            */

            SPSite site = null;
            SPFeatureCollection coll;

            try
            {
                if (Scope == "Farm")
                {
                    SPWebService websvc = SPFarm.Local.Servers.GetValue<SPWebService>(string.Empty);

                    coll = websvc.Features;
                }
                else if (Scope == "WebApplication")
                {
                    coll = SPWebApplication.Lookup(new Uri(this.ParentUrl)).Features;
                }
                else
                {
                    site = new SPSite(this.ParentUrl);
                    if (Scope == "Site")
                    {
                        coll = site.Features;
                    }
                    else
                    {
                        SPWeb web = site.OpenWeb();
                        coll = web.Features;
                    }
                }

                if (this.Title == "Activated")
                {
                    return ExFeature.CreateActivatedCollection(coll, this.ParentUrl);
                }
                else
                {
                    return ExFeature.CreateDeactivatedCollection(coll, this.ParentUrl, this.Scope);
                }
            }
            finally
            {
                if (site != null)
                    site.Dispose();
            }
        }
        
        public object GetProperties(bool UseSPObjectModel)
        {
            return null;
        }

        public static List<IExplorerObjectContainer> CreateCollection(string Scope, string ParentUrl)
        {
            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();

            ExFeaturesCollection container;

            /*
            if (Scope == "Farm")
            {
                container = new ExFeaturesCollection();
                container.Title = "Installed";

                ret.Add(container);
            }
            */


            container = new ExFeaturesCollection();
            container.ParentUrl = ParentUrl;
            container.Scope = Scope;
            container.Title = "Activated";

            ret.Add(container);

            container = new ExFeaturesCollection();
            container.ParentUrl = ParentUrl;
            container.Scope = Scope;
            container.Title = "Deactivated";

            ret.Add(container);

            return ret;
        }
    }

    [DataContract]
    public class ExFeature : IExplorerObjectContainer
    {
        [DataMember]
        public string Title
        {
            get;
            set;
        }

        [DataMember]
        public string Name
        {
            get;
            set;
        }

        [DataMember]
        public string Scope
        {
            get;
            set;
        }

        [DataMember]
        public string ParentUrl
        {
            get;
            set;
        }

        [DataMember]
        public bool CanHaveChildren
        {
            get { return false; }
            set { }
        }

        [DataMember]
        public Dictionary<string, Uri> BrowseToURLs { get; set; }

        public List<string> GetSubGroups()
        {
            return null;
        }

        public List<IExplorerObjectContainer> GetChildren(string SubGroup)
        {
            return null;
        }
        
        public object GetProperties(bool UseSPObjectModel)
        {
            try
            {
                SPFeatureDefinition def = SPFarm.Local.FeatureDefinitions[this.Title];
                if (UseSPObjectModel)
                {
                    return def;
                }
                else
                {
                    return Common.GetPropertiesFromObject(def);
                }
            }
            catch
            {
                return null;
            }
        }

        public static List<IExplorerObjectContainer> CreateFarmInstalledCollection()
        {
            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();

            foreach (SPFeatureDefinition feature in SPFarm.Local.FeatureDefinitions)
            {
                ExFeature container = new ExFeature();
                container.Title = feature.DisplayName;
                container.Name = feature.Name;

                ret.Add(container);
            }

            return ret;
        }

        public static List<IExplorerObjectContainer> CreateActivatedCollection(SPFeatureCollection collection, string ParentUrl)
        {
            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();

            foreach (SPFeature feature in collection)
            {
                ExFeature container = new ExFeature();
                container.ParentUrl = ParentUrl;

                if (feature.Definition != null)
                {
                    container.Title = feature.Definition.DisplayName;
                    container.Name = Path.GetFileName(feature.Definition.RootDirectory);
                }
                else
                {
                    SPFeatureDefinition featureDef = SPFarm.Local.FeatureDefinitions[feature.DefinitionId];
                    container.Title = featureDef.DisplayName;
                    container.Name = Path.GetFileName(featureDef.RootDirectory);
                }

                ret.Add(container);
            }

            return ret;
        }

        public static List<IExplorerObjectContainer> CreateDeactivatedCollection(SPFeatureCollection collection, string ParentUrl, string Scope)
        {
            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();

            List<Guid> list = new List<Guid>();
            foreach (SPFeature feature in collection)
            {
                list.Add(feature.DefinitionId);
            }

            foreach (SPFeatureDefinition def in SPFarm.Local.FeatureDefinitions)
            {
                if (def.Scope.ToString() != Scope || list.Contains(def.Id))
                    continue;

                ExFeature container = new ExFeature();
                container.Title = def.DisplayName;
                container.Name = Path.GetFileName(def.RootDirectory);
                container.ParentUrl = ParentUrl;

                ret.Add(container);
            }

            return ret;
        }

    }


    [DataContract]
    public class ExEventReceiver : IExplorerObjectContainer
    {
        public List<string> GetSubGroups()
        {
            return null;
        }

        public List<IExplorerObjectContainer> GetChildren(string SubGroup)
        {
            return null;
        }

        [DataMember]
        public bool CanHaveChildren
        {
            get { return false; }
            set { }
        }

        [DataMember]
        public string Title
        {
            get;
            set;
        }

        [DataMember]
        public Dictionary<string, Uri> BrowseToURLs { get; set; }

        public object GetProperties(bool UseSPObjectModel)
        {
            return null;
        }

        public static List<IExplorerObjectContainer> CreateCollection(SPEventReceiverDefinitionCollection collection)
        {
            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();

            foreach (SPEventReceiverDefinition eventrec in collection)
            {
                ExEventReceiver container = new ExEventReceiver();
                container.Title = eventrec.Type.ToString() + " - " + eventrec.Class + ", " + eventrec.Assembly;
                ret.Add(container);
            }

            return ret;
        }
    }

    [DataContract]
    public class ExFarmSolution : IExplorerObjectContainer
    {
        public List<string> GetSubGroups()
        {
            return null;
        }

        public List<IExplorerObjectContainer> GetChildren(string SubGroup)
        {
            return null;
        }

        [DataMember]
        public bool CanHaveChildren
        {
            get { return false; }
            set { }
        }

        [DataMember]
        public string Title
        {
            get;
            set;
        }

        [DataMember]
        public Dictionary<string, Uri> BrowseToURLs { get; set; }

        public object GetProperties(bool UseSPObjectModel)
        {
            return null;
        }

        public static List<IExplorerObjectContainer> CreateCollection(SPSolutionCollection collection)
        {
            string admin_url = SPAdministrationWebApplication.Local.GetResponseUri(SPUrlZone.Default).ToString();
            if (admin_url.EndsWith("/"))
                admin_url = admin_url.Substring(0, admin_url.Length - 1);

            List<IExplorerObjectContainer> ret = new List<IExplorerObjectContainer>();
            foreach (SPSolution solution in collection)
            {
                ExFarmSolution container = new ExFarmSolution();
                container.Title = solution.Name;

                container.BrowseToURLs = new Dictionary<string, Uri>();
                container.BrowseToURLs.Add("View status", new Uri(admin_url + "/_admin/SolutionStatus.aspx?ItemName=" + SPEncode.UrlEncode(solution.Name) + "&Lcid=0"));

                ret.Add(container);
            }

            return ret;
        }
    }

}
